<template>
  <div>
    <div v-for="(item, index) in options" :key="index">
      <template v-if="values.includes(item.value)">
        <span v-if="!showDict">
          <span v-if="item.value === '1'" class="circle"></span>
          <span v-else class="circle red"></span>
          {{ item.label + '' }}
        </span>
        <span
          v-else-if="(item.listClass == 'default' || item.listClass == '') && (item.cssClass == '' || item.cssClass == null)"
          :class="item.cssClass"
        >{{ item.label + " " }}</span>

        <a-tag
          v-else
          :color="handleColor(item.listClass)"
          :size="size"
          :class="item.cssClass"
        >{{ item.label + " " }}</a-tag>
      </template>
    </div>
    <!-- 未匹配的项 -->
    <div v-if="unmatch && showValue">{{ unmatchString }}</div>
  </div>
</template>
  
<script lang="ts" setup>
import { ref, computed, defineProps } from 'vue';

// 定义 props 的类型
interface Option {
  value: string;
  label: string;
  listClass: string;
  cssClass: string;
}

interface Props {
  options?: Option[]; // 数据
  value?: number | string | Array<number | string>; // 当前的值
  showValue?: boolean; // 当未找到匹配的数据时，显示 value
  showDict?: boolean;
  separator?: string; // 分隔符
  size?: 'small' | 'medium' | 'large'; // tag尺寸 'small' | 'medium' | 'large'
}

// 定义 props
const props = withDefaults(defineProps<Props>(), {
  options: () => [],
  value: '',
  showValue: true,
  showDict: true,
  separator: ',',
  size: 'medium',
});

// 将 value 转换为数组
const values = computed(() => {
  if (
    props.value === null ||
    typeof props.value === 'undefined' ||
    props.value === ''
  )
    return [];
  return Array.isArray(props.value)
    ? props.value.map((item) => String(item))
    : String(props.value).split(props.separator);
});

// 记录未匹配的项
const unmatchArray = ref<(string | number)[]>([]);

// 计算未匹配的项
const unmatch = computed(() => {
  unmatchArray.value = [];
  // 没有 value 或 options 为空时不显示
  if (
    props.value === null ||
    typeof props.value === 'undefined' ||
    props.value === '' ||
    !Array.isArray(props.options) ||
    props.options.length === 0
  ) {
    return false;
  }

  // 检查是否有未匹配项
  let unmatchFlag = false;
  values.value.forEach((item) => {
    if (!props.options.some((v) => v.value === item)) {
      unmatchArray.value.push(item);
      unmatchFlag = true;
    }
  });
  return unmatchFlag;
});

// 处理数组，将其转换为字符串
const unmatchString = computed(() => {
  if (unmatchArray.value.length === 0) return '';
  return unmatchArray.value.join(' ').trim();
});

// 将tag类型转为a-tag颜色
const handleColor = (listClass: string) => {
  if (listClass === 'info') {
    return 'gray';
  } else if (listClass === 'primary') {
    return 'blue';
  } else if (listClass === 'success') {
    return 'green';
  } else if (listClass === 'warning') {
    return 'orangered';
  } else if (listClass === 'danger') {
    return 'red';
  } else {
    return 'gray';
  }
};
</script>
  
<style scoped lang="less">
.el-tag + .el-tag {
  margin-left: 10px;
}
</style>
  